﻿using System.Collections.ObjectModel;
using System.Data.Entity.Infrastructure;
using System.Linq;
using SellAvi.Model;

namespace SellAvi.Services
{

    /// <summary>
    /// The Interface defining methods for Create Employee and Read All Employees  
    /// </summary>
    public interface IDataAccessService
    {
        DbChangeTracker ChangeTracker { get; }
        ObservableCollection<AvitoProduct> GetProducts();
        ObservableCollection<AvitoUser> GetUsers { get; }
        ObservableCollection<TCustomParam> GetCustomParams();
        void SaveCustomParam(TCustomParam cParameter);
        void CreateProduct(AvitoProduct product);
        void SaveContext();
        T GetDetachedEntity<T>(T entityObject) where T : class;
        AvitoUser SaveUser(AvitoUser user);
        void UpdateUserFrom(AvitoUser userFrom, AvitoUser userTo);
        void DeleteUser(AvitoUser user);
        void DeleteProduct(AvitoProduct product);
        void DeleteImage(AvitoImage product);
        void TruncateAllCustomParams();
        void DeleteCustomParam(int id);
        AvitoProduct GetProduct(int id);
        AvitoUser GetLastAvitoUser();
        AvitoUser GetAvitoUser(int id);

        //Справочники
        Collection<TCategory> GetCategories { get; set; }
        Collection<TRegion> GetRegions { get; set; }
        Collection<TParam> GetParams { get; set; }
    }

    /// <summary>
    /// Class implementing IDataAccessService interface and implementing
    /// its methods by making call to the Entities using CompanyEntities object
    /// </summary>
    public class DataAccessService : IDataAccessService
    {
        AvitoModel context;
        public DataAccessService()
        {
            context = new AvitoModel();
        }

        public DbChangeTracker ChangeTracker
        {
            get { return context.ChangeTracker; }
        }

        public ObservableCollection<AvitoProduct> GetProducts()
        {
            ObservableCollection<AvitoProduct> products = new ObservableCollection<AvitoProduct>();
            foreach (var item in context.AvitoProducts)
            {
                products.Add(item);
            }
            return products;
        }

        public ObservableCollection<AvitoUser> GetUsers
        {
            get
            {
                return new ObservableCollection<AvitoUser>(context.AvitoUsers);
            }

            /*ObservableCollection<AvitoUser> user = new ObservableCollection<AvitoUser>();
            foreach (var item in context.AvitoUsers)
            {
                user.Add(item);
            }
            return user;*/
        }

        public ObservableCollection<TCustomParam> GetCustomParams()
        {
            return new ObservableCollection<TCustomParam>(context.TCustomParams);

        }

        public void SaveCustomParam(TCustomParam cParameter)
        {
            context.TCustomParams.Add(cParameter);
        }

        public void CreateProduct(AvitoProduct product)
        {
            context.AvitoProducts.Add(product);
        }

        public void SaveContext()
        {
            context.SaveChanges();
        }

        public AvitoUser SaveUser(AvitoUser user)
        {
            context.AvitoUsers.Add(user);
            context.SaveChanges();
            return GetDetachedEntity(user);
        }

        public T GetDetachedEntity<T>(T entityObject) where T : class
        {
            //T entity = context.Set<T>().Create<T>();
            return (T)context.Entry(entityObject).GetDatabaseValues().ToObject();

        }

        public void UpdateUserFrom(AvitoUser userFrom, AvitoUser userTo)
        {
            context.Entry(userTo).CurrentValues.SetValues(userFrom);
            context.SaveChanges();
        }

        public void DeleteUser(AvitoUser user)
        {
            context.AvitoUsers.Remove(user);
            context.SaveChanges();
        }

        public void DeleteImage(AvitoImage image)
        {
            context.AvitoImages.Remove(image);
            context.SaveChanges();
        }

        public void TruncateAllCustomParams()
        {
            foreach (var param in GetCustomParams())
            {
                context.TCustomParams.Remove(param);
            }
            context.SaveChanges();
        }

        public void DeleteCustomParam(int id)
        {
            context.TCustomParams.Remove(GetCustomParams().FirstOrDefault(x => x.Id == id));
            context.SaveChanges();
        }

        public AvitoProduct GetProduct(int id)
        {
            return context.AvitoProducts.FirstOrDefault(a => a.Id == id) ?? context.AvitoProducts.FirstOrDefault();
        }

        public AvitoUser GetLastAvitoUser()
        {
            return context.AvitoUsers.AsNoTracking().OrderByDescending(x => x.Id).FirstOrDefault();
        }



        public AvitoUser GetAvitoUser(int id)
        {
            return context.AvitoUsers.FirstOrDefault(a => a.Id == id);
        }

        public void DeleteProduct(AvitoProduct product)
        {
            context.AvitoProducts.Remove(product);
            context.SaveChanges();
        }

        //
        //  Справочники
        //

        Collection<TParam> prm;
        public Collection<TParam> GetParams
        {
            get
            {
                if (prm != null) return prm;
                prm = new Collection<TParam>();
                foreach (var item in context.TParams)
                {
                    prm.Add(item);
                }
                return prm;
            }
            set { prm = value; }

        }

        private Collection<TRegion> reg;
        public Collection<TRegion> GetRegions
        {
            get
            {
                if (reg != null) return reg;
                reg = new Collection<TRegion>();
                foreach (var item in context.TRegions)
                {
                    reg.Add(item);
                }
                return reg;
            }
            set { reg = value; }

        }

        private Collection<TCategory> cat;

        public Collection<TCategory> GetCategories
        {
            get
            {
                if (cat != null) return cat;
                cat = new Collection<TCategory>();
                foreach (var item in context.TCategories)
                {
                    cat.Add(item);
                }
                return cat;

            }
            set { cat = value; }

        }
    }


}
